package com.supostacks.infrastructure.repository;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supostacks.domain.repository.ICardKeyRepository;
import com.supostacks.domain.vo.CardKeyVo;
import com.supostacks.domain.vo.ResourceInfoVo;
import com.supostacks.infrastructure.context.DefaultContext;
import com.supostacks.infrastructure.context.EntityUtil;
import com.supostacks.infrastructure.dao.CardKeyDao;
import com.supostacks.infrastructure.po.CardKey;
import com.supostacks.infrastructure.po.ResourceInfo;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class CardKeyRepository extends DefaultContext implements ICardKeyRepository {

    @Resource
    private CardKeyDao cardKeyDao;

    @Override
    public String insert(CardKeyVo cardKeyVo) {
        try {
            CardKey cardKey = new CardKey();
            EntityUtil.copyFields(cardKeyVo, cardKey);

            int insert = cardKeyDao.insert(cardKey);
            if (insert > 0) {
                return cardKey.getId();
            }
            return null;

        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteById(String id) {
        cardKeyDao.deleteById(id);
    }

    @Override
    public String updateById(CardKeyVo cardKeyVo) {
        try {
            CardKey cardKey = new CardKey();
            EntityUtil.copyFields(cardKeyVo, cardKey);
            int i = cardKeyDao.updateById(cardKey);
            if (i > 0) {
                return cardKey.getId();
            }
            return "";
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public CardKeyVo selectById(String id) {
        CardKey cardKey = cardKeyDao.selectById(id);
        if (cardKey != null) {
            return poToVo(cardKey);
        }
        return null;
    }

    @Override
    public List<CardKeyVo> selectList(JSONObject param) {
        QueryWrapper<CardKey> queryWrapper = where(param);
        List<CardKey> cardKeyInfos = cardKeyDao.selectList(queryWrapper);
        return buildList(cardKeyInfos);
    }

    @Override
    public JSONObject selectByPage(JSONObject options, int pageNo, int pageSize) {
        QueryWrapper<CardKey> queryWrapper = where(options);
        queryWrapper = orderBy(queryWrapper, options.getJSONObject("orderBy"));

        Page<CardKey> infos = new Page<>(pageNo, pageSize);
        IPage<CardKey> iPage = cardKeyDao.selectPage(infos, queryWrapper);

        List<CardKey> records = iPage.getRecords();
        for (CardKey record : records) {
            record.setCodeKey(hiddenKey(record.getCodeKey()));
        }

        JSONObject result = new JSONObject();
        result.put("total", iPage.getTotal());
        result.put("list", records);

        return result;
    }

    @Override
    public CardKeyVo selectCardKeyByCode(String code) {
        LambdaQueryWrapper<CardKey> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CardKey::getCodeKey, code);
        CardKey cardKey = cardKeyDao.selectOne(queryWrapper);
        if (cardKey != null) {
            return poToVo(cardKey);
        }
        return null;
    }

    public String hiddenKey(String key) {
        StringBuilder nKey = new StringBuilder();
        for (int i = 4; i < key.length() - 15; i++) {
            nKey.append("*");
        }
        return key.substring(0, 4) + nKey + key.substring(key.length() - 4);
    }

    public List<CardKeyVo> buildList(List<CardKey> cardKeys) {
        return cardKeys.stream().map(this::poToVo).collect(Collectors.toList());
    }

    public CardKeyVo poToVo(CardKey cardKey) {
        try {
            CardKeyVo cardKeyVo = new CardKeyVo();
            EntityUtil.copyFields(cardKey, cardKeyVo);
            return cardKeyVo;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
